<template>
    <div class="screen-wrapper" ref="screenWrapper" :style="wrapperStyle">
        <slot></slot>
    </div>
</template>

<script setup>
    import {ref, watch, computed, onMounted, onUnmounted, nextTick} from "vue";

    /**
     * 防抖函数
     * @param {Function} fn
     * @param {Number} delay
     */
    function useDebounce(fn, delay = 100) {
        let timer = null;
        return (...args) => {
            clearTimeout(timer);
            timer = setTimeout(() => {
                fn(...args);
            }, delay);
        };
    }

    // ✅ 组件 Props
    const props = defineProps({
        width: {type: [String, Number], default: 1920},
        height: {type: [String, Number], default: 1080},
        fullScreen: {type: Boolean, default: false},
        autoScale: {type: [Object, Boolean], default: true},
        selfAdaption: {type: Boolean, default: true},
        delay: {type: Number, default: 500},
        boxStyle: {type: Object, default: () => ({})},
        wrapperStyle: {type: Object, default: () => ({})}
    });

    // ✅ 响应式变量
    const screenWrapper = ref(null);
    const currentWidth = ref(0);
    const currentHeight = ref(0);
    const originalWidth = ref(0);
    const originalHeight = ref(0);

    // ✅ 计算属性
    const screenWrapperEl = computed(() => screenWrapper.value);

    // ✅ 初始化尺寸
    const initSize = () => {
        return new Promise((resolve) => {
            nextTick(() => {
                if (screenWrapperEl.value) {
                    const parent = screenWrapperEl.value.parentNode;
                    if (parent) {
                        parent.style.overflow = "hidden";
                        parent.scrollLeft = 0;
                        parent.scrollTop = 0;
                    }

                    if (props.width && props.height) {
                        currentWidth.value = props.width;
                        currentHeight.value = props.height;
                    } else {
                        currentWidth.value = screenWrapperEl.value.clientWidth;
                        currentHeight.value = screenWrapperEl.value.clientHeight;
                    }

                    if (!originalWidth.value || !originalHeight.value) {
                        originalWidth.value = window.screen.width;
                        originalHeight.value = window.screen.height;
                    }
                }
                resolve();
            });
        });
    };

    // ✅ 更新容器大小
    const updateSize = () => {
        const wrapper = screenWrapperEl.value;
        if (currentWidth.value && currentHeight.value) {
            wrapper.style.width = `${currentWidth.value}px`;
            wrapper.style.height = `${currentHeight.value}px`;
        } else {
            wrapper.style.width = `${originalWidth.value}px`;
            wrapper.style.height = `${originalHeight.value}px`;
        }
    };

    // ✅ 处理缩放
    const handleAutoScale = (scale) => {
        if (!props.autoScale) return;
        const wrapper = screenWrapperEl.value;
        const domWidth = wrapper.clientWidth;
        const domHeight = wrapper.clientHeight;
        const currentWidth = document.body.clientWidth;
        const currentHeight = document.body.clientHeight;

        wrapper.style.transform = `scale(${scale},${scale})`;
        let mx = Math.max((currentWidth - domWidth * scale) / 2, 0);
        let my = Math.max((currentHeight - domHeight * scale) / 2, 0);

        if (typeof props.autoScale === "object") {
            if (!props.autoScale.x) mx = 0;
            if (!props.autoScale.y) my = 0;
        }
        wrapper.style.margin = `${my}px ${mx}px`;
    };

    // ✅ 计算缩放比例
    const updateScale = () => {
        const wrapper = screenWrapperEl.value;
        const currentWidthDiv = document.body.clientWidth;
        const currentHeightDiv = document.body.clientHeight;
        const realWidth = currentWidth.value || originalWidth.value;
        const realHeight = currentHeight.value || originalHeight.value;

        const widthScale = currentWidthDiv / realWidth;
        const heightScale = currentHeightDiv / realHeight;

        if (props.fullScreen) {
            wrapper.style.transform = `scale(${widthScale},${heightScale})`;
            return;
        }
        const scale = Math.min(widthScale, heightScale);
        handleAutoScale(scale);
    };

    // ✅ 监听 resize 事件
    const onResize = useDebounce(() => {
        resize();
    }, props.delay);

    const addListener = () => window.addEventListener("resize", onResize);
    const clearListener = () => window.removeEventListener("resize", onResize);

    // ✅ 初始化自适应
    const resize = async () => {
        if (!props.selfAdaption) return;
        await initSize();
        updateSize();
        updateScale();
    };

    // ✅ 监听 selfAdaption 变化
    watch(
        () => props.selfAdaption,
        (val) => {
            if (val) {
                resize();
                addListener();
            } else {
                clearListener();
                clearStyle();
            }
        },{
            immediate: true
        }
    );

    // ✅ 清除样式
    const clearStyle = () => {
        const wrapper = screenWrapperEl.value;
        wrapper.parentNode.style.overflow = "auto";
        wrapper.style = "";
    };

    // ✅ 生命周期管理
    onMounted(() => {
        nextTick(() => {
            if (props.selfAdaption) {
                resize();
                addListener();
            }
        });
    });

    onUnmounted(() => {
        clearListener();
    });
</script>

<style scoped>
    .screen-wrapper {
        transition-property: all;
        transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
        transition-duration: 500ms;
        position: relative;
        overflow: hidden;
        z-index: 100;
        transform-origin: left top;
    }
</style>
